home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Python / mystrtoul.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  3.2 KB  |  159 lines

  1. #include "Python.h"
  2.  
  3. #if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE)
  4. #define _SGI_MP_SOURCE
  5. #endif
  6.  
  7. /* Convert a possibly signed character to a nonnegative int */
  8. /* XXX This assumes characters are 8 bits wide */
  9. #ifdef __CHAR_UNSIGNED__
  10. #define Py_CHARMASK(c)        (c)
  11. #else
  12. #define Py_CHARMASK(c)        ((c) & 0xff)
  13. #endif
  14.  
  15. /* strtol and strtoul, renamed to avoid conflicts */
  16.  
  17. /*
  18. **    strtoul
  19. **        This is a general purpose routine for converting
  20. **        an ascii string to an integer in an arbitrary base.
  21. **        Leading white space is ignored.  If 'base' is zero
  22. **        it looks for a leading 0, 0x or 0X to tell which
  23. **        base.  If these are absent it defaults to 10.
  24. **        Base must be 0 or between 2 and 36 (inclusive).
  25. **        If 'ptr' is non-NULL it will contain a pointer to
  26. **        the end of the scan.
  27. **        Errors due to bad pointers will probably result in
  28. **        exceptions - we don't check for them.
  29. */
  30.  
  31. #include <ctype.h>
  32. #ifndef DONT_HAVE_ERRNO_H
  33. #include <errno.h>
  34. #endif
  35.  
  36. unsigned long
  37. PyOS_strtoul(str, ptr, base)
  38. register char *    str;
  39. char **        ptr;
  40. int        base;
  41. {
  42.     register unsigned long    result;    /* return value of the function */
  43.     register int        c;    /* current input character */
  44.     register unsigned long    temp;    /* used in overflow testing */
  45.     int                ovf;    /* true if overflow occurred */
  46.  
  47.     result = 0;
  48.     ovf = 0;
  49.  
  50. /* catch silly bases */
  51.     if (base != 0 && (base < 2 || base > 36))
  52.     {
  53.     if (ptr)
  54.         *ptr = str;
  55.     return 0;
  56.     }
  57.  
  58. /* skip leading white space */
  59.     while (*str && isspace(Py_CHARMASK(*str)))
  60.     str++;
  61.  
  62. /* check for leading 0 or 0x for auto-base or base 16 */
  63.     switch (base)
  64.     {
  65.     case 0:        /* look for leading 0, 0x or 0X */
  66.     if (*str == '0')
  67.     {
  68.         str++;
  69.         if (*str == 'x' || *str == 'X')
  70.         {
  71.         str++;
  72.         base = 16;
  73.         }
  74.         else
  75.         base = 8;
  76.     }
  77.     else
  78.         base = 10;
  79.     break;
  80.  
  81.     case 16:    /* skip leading 0x or 0X */
  82.     if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
  83.         str += 2;
  84.     break;
  85.     }
  86.  
  87. /* do the conversion */
  88.     while ((c = Py_CHARMASK(*str)) != '\0')
  89.     {
  90.     if (isdigit(c) && c - '0' < base)
  91.         c -= '0';
  92.     else
  93.     {
  94.         if (isupper(c))
  95.         c = tolower(c);
  96.         if (c >= 'a' && c <= 'z')
  97.         c -= 'a' - 10;
  98.         else    /* non-"digit" character */
  99.         break;
  100.         if (c >= base)    /* non-"digit" character */
  101.         break;
  102.     }
  103.     temp = result;
  104.     result = result * base + c;
  105. #ifndef MPW
  106.     if(base == 10) {
  107.         if(((long)(result - c) / base != (long)temp))    /* overflow */
  108.             ovf = 1;
  109.     }
  110.     else {
  111.         if ((result - c) / base != temp)    /* overflow */
  112.             ovf = 1;
  113.     }
  114. #endif
  115.     str++;
  116.     }
  117.  
  118. /* set pointer to point to the last character scanned */
  119.     if (ptr)
  120.     *ptr = str;
  121.     if (ovf)
  122.     {
  123.     result = (unsigned long) ~0L;
  124.     errno = ERANGE;
  125.     }
  126.     return result;
  127. }
  128.  
  129. long
  130. PyOS_strtol(str, ptr, base)
  131. char *    str;
  132. char ** ptr;
  133. int    base;
  134. {
  135.     long result;
  136.     char sign;
  137.     
  138.     while (*str && isspace(Py_CHARMASK(*str)))
  139.         str++;
  140.     
  141.     sign = *str;
  142.     if (sign == '+' || sign == '-')
  143.         str++;
  144.     
  145.     result = (long) PyOS_strtoul(str, ptr, base);
  146.     
  147.     /* Signal overflow if the result appears negative,
  148.        except for the largest negative integer */
  149.     if (result < 0 && !(sign == '-' && result == -result)) {
  150.         errno = ERANGE;
  151.         result = 0x7fffffff;
  152.     }
  153.     
  154.     if (sign == '-')
  155.         result = -result;
  156.     
  157.     return result;
  158. }
  159.